﻿#include "RegextoNFA.h"
RegextoNFA regexToNFA() {
    //由于OP里面存在||,所以不同正则间使用空格分隔代表| l代表letter，_代表下划线，0代表数字(也可以是d，但是为了使用已经有的函数)，
    //[lu]代表l|u
    string Regex = "+ - * / % = > < == <= >= != && || ( ) { } , ; [l_][l_0]* -?00* '[l0]' -?00*.0* ! : '\\l'";
    //下面给出正则对应的输出(终态)
    vector<WordType> finalState = {
        OP_ADD, OP_SUB,OP_MUL,OP_DIV,OP_MOD,OP_ASSIGN,OP_GT,OP_LT, OP_EQ,OP_LE,OP_GE,OP_NE, OP_AND, OP_OR,SE_LBRAC, SE_RBRAC,
        SE_LCBRAC,SE_RCBRAC,SE_COMMA,SE_SEMI,IDN,INT_VAL,CHAR_VAL,FLOAT_VAL,OP_EXC,SE_COLON,CHAR_B,
    };
    stringstream ss(Regex);
    string target;

    // 创建初始状态
    int stateIndex = 0;
    int finalIndex = 0;
    State* startState = new State(stateIndex++);
    set<State*, StatePtrCompare> endStates;
    set<State*, StatePtrCompare> allStates = { startState };
    while (getline(ss, target, ' '))  {
        //如获得[l_][l_0]*
        // if (target == "\l") {
        //     int a = 10;
        // }
        State* currentState = startState;
        for (size_t i = 0; i < target.length(); i++) {
            //创建一个新状态，startState通过输入InputCharType到达该状态
            State* newState = new State(stateIndex++);
            allStates.insert(newState);
            //需要往后看一个符号
            if (target[i] == '[') {
                //[...]构成一种输入，查看]后面是否有？或者*，来判断当前状态的构成
                for (i = i + 1; i < target.length() && target[i] != ']'; i++) {
                    InputCharType input = getInputCharType(target[i]);
                    if (input != EPSILON) {
                        // 添加转移函数，从当前状态向新状态转移
                        currentState->addTransition(input, newState);
                    }
                }
            }
            else {
                InputCharType input = getInputCharType(target[i]);
                currentState->addTransition(input, newState);
            }
            //往后查看一个输入
            if (i + 1 < target.length() && target[i + 1] == '?') {
                //创建EPSILON转移状态
                State* epsState = new State(stateIndex++);
                allStates.insert(epsState);
                currentState->addTransition(EPSILON, epsState);
                newState->addTransition(EPSILON, epsState);
                currentState = epsState;
                // 跳过'?'字符
                i++;
            }
            else if (i + 1 < target.length() && target[i + 1] == '*') {
                State* epsState = new State(stateIndex++);
                allStates.insert(epsState);
                currentState->addTransition(EPSILON, epsState);
                newState->addTransition(EPSILON, epsState);
                epsState->addTransition(EPSILON, currentState);
                currentState = epsState;
                // 跳过'*'字符
                i++;
            }
            else {
                currentState = newState;
            }
            //判断是否是终止状态
            if (i == (target.length() - 1)) {
                // 到达最后一个字符，将当前状态设置为终止状态
                currentState->setFinalState(true, finalState[endStates.size()]);
                endStates.insert(currentState);
            }
        }//for
    }
    // 返回字符集合对应的NFA
    return RegextoNFA(startState, endStates, allStates);
}

void printNFA(const RegextoNFA& nfa) {
    cout << "Start state: " << nfa.startState->id << endl;
    cout << "End states: " << endl;
    for (auto state : nfa.endStates) {
        cout << state->id << " " << getWordTypeName(state->wordType) << " " << (state->isFinalState == true) << endl;
    }
    cout << endl;

    cout << "States and transitions:" << endl;
    for (auto state : nfa.states) {
        cout << "State " << state->id << ":" << endl;
        for (auto transition : state->transitions) {
            cout << "\tInput " << getInputChartypeName(transition.first) << ": ";
            for (auto targetState : transition.second) {
                cout << targetState->id << " ";
            }
            cout << endl;
        }
    }
}



